﻿using System;
using System.IO;
using System.Text;
using System.Web;

namespace down2.api
{
    /// <summary>
    /// 下载指定路径下的文件数据
    /// </summary>
    public partial class file : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            var path = Request.QueryString["path"];
            if (string.IsNullOrEmpty(path))
            {
                Response.StatusCode = 500;
                Response.Write("路径为空");
                Response.End();
            }
            path = path.Trim();
            path = path.Replace("/", "\\");
            path = Base64Encoder.build().decode(path);
            if(!File.Exists(path))
            {
                Response.StatusCode = 500;
                Response.Write("文件不存在");
                Response.End();
            }

            //
            var fileName = Path.GetFileName(path);
            var filePath = path;
            string fnUtf8 = Encoding.UTF8.GetString(Encoding.GetEncoding("gb2312").GetBytes(fileName));
            fnUtf8 = HttpUtility.UrlEncode(fileName);
            Response.ContentType = "application/octet-stream";
            Response.AddHeader("Content-Disposition", "attachment; filename="+fnUtf8);
            //设置文件编码。utf-8编码的中文需要使用urlencode转换。
            Response.AddHeader("Content-Type", "application/octet-stream;");
            Response.AddHeader("Pragma", "No-cache");
            Response.AddHeader("Cache-Control", "No-cache");
            Response.AddHeader("Expires", "0");

            Stream iStream = null;
            try
            {
                // Open the file.
                iStream = new System.IO.FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);

                // Total bytes to read:
                long blockSize = iStream.Length;
                long blockBegin = 0;
                long blockEnd = blockSize - 1;
                long fileSize = blockSize;

                string range = Request.Headers.Get("Range");
                if (!string.IsNullOrEmpty(range))
                {
                    //清除bytes=
                    int pos = range.IndexOf("=");
                    if (pos != -1) range = range.Substring(pos + 1);

                    /*
                     * 1-
                     * -1
                     * 0-1
                     */
                    string[] indexs = range.Split("-".ToCharArray());
                    //-1
                    if (string.IsNullOrEmpty(indexs[0]))
                    {
                        blockSize = long.Parse(indexs[1]);
                        iStream.Seek(long.Parse(indexs[1]), SeekOrigin.End);
                        blockEnd = iStream.Length - 1;
                        blockBegin = iStream.Length - blockSize;
                    }//1-
                    else if (string.IsNullOrEmpty(indexs[1]))
                    {
                        iStream.Seek(long.Parse(indexs[0]), SeekOrigin.Begin);
                        blockSize = iStream.Length - long.Parse(indexs[0]);
                        blockBegin = long.Parse(indexs[0]);
                        blockEnd = (blockBegin + blockSize) - 1;
                    }//1-1
                    else
                    {
                        iStream.Seek(long.Parse(indexs[0]), SeekOrigin.Begin);
                        blockSize = (long.Parse(indexs[1]) - long.Parse(indexs[0])) + 1;
                        blockBegin = long.Parse(indexs[0]);
                        blockEnd = long.Parse(indexs[1]);
                    }
                }
                Response.AddHeader("Content-Range", string.Format("bytes {0}-{1}/{2}", blockBegin, blockEnd, fileSize));
                //if (blockSize > 1)
                //{
                //    Response.AddHeader("Content-Length", "100");
                //    blockSize = 100;
                //}
                //else
                //{
                Response.AddHeader("Content-Length", blockSize.ToString());
                //}

                int buf_size = Math.Min(1048576, (int)blockSize);
                byte[] buffer = new Byte[buf_size];
                int length = 0;

                while (blockSize > 0 && Response.IsClientConnected)
                {
                    // Read the data in buffer.
                    length = iStream.Read(buffer, 0, buf_size);
                    length = (int)blockSize > length ? length : (int)blockSize;
                    blockSize -= length;

                    // Write the data to the current output stream.
                    Response.OutputStream.Write(buffer, 0, length);

                    // Flush the data to the HTML output.
                    Response.Flush();
                }
            }
            catch (Exception ex)
            {
                // Trap the error, if any.
                Response.Write("Error : " + ex.Message);
            }
            finally
            {
                if (iStream != null)
                {
                    //Close the file.
                    iStream.Close();
                }
            }
        }
    }
}